package testconditionsAPI;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import conditionsAPI.AndDomainCondition;
import conditionsAPI.ConditionDuplicatedException;
import conditionsAPI.ConditionsConfiguration;
import conditionsAPI.NotDomainCondition;
import conditionsAPI.SimpleDomainCondition;

public class TestNotDomainCondition {

	private SimpleDomainCondition simpleCondition1;
	private SimpleDomainCondition simpleCondition2;
	private SimpleDomainCondition simpleCondition3;
	private AndDomainCondition andCondition;
	private NotDomainCondition notCondition;
	
	@Before
	public void setUp(){
		try {
			this.simpleCondition1 = new StubSimpleDomainCondition("simple1");
			this.simpleCondition2 = new StubSimpleDomainCondition("simple2");
			this.simpleCondition3 =  new StubSimpleDomainCondition("simple3");
			this.andCondition = new AndDomainCondition("composed");
			this.notCondition = null;
		} catch (ConditionDuplicatedException e) {
			e.printStackTrace();
		}
	}
	
	@After
	public void tearDown(){
		ConditionsConfiguration.reset();
	}
	
	@Test
	public void createTwoNotConditionWithSameConditionToCancelAndThrowException(){
		@SuppressWarnings("unused")
		NotDomainCondition notConditionTwin = null;
		try {
			this.notCondition = new NotDomainCondition(this.simpleCondition1);
			notConditionTwin = new NotDomainCondition(this.simpleCondition1);
			assertTrue(false);
		} catch (ConditionDuplicatedException e) {
			assertTrue(true);
		}
	}
	
	@Test
	public void setConditionToCancelGetNotConditionStateDifferentFromConditionToCancelState() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.simpleCondition1);
		
		assertFalse(this.notCondition.isTrue() == this.simpleCondition1.isTrue());
	}
	
	@Test
	public void setConditionToCancelMakeConditionTrueGetNotConditionStateFalse() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.simpleCondition1);
		
		ConditionsConfiguration.processObject(this.simpleCondition1);
		
		assertFalse(this.notCondition.isTrue() == this.simpleCondition1.isTrue());
	}
	
	@Test
	public void setConditionToCancelAddPreConditionMakePreConditionTrueCheckConditionToCancelIsFalse() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.simpleCondition1);
		this.notCondition.addPreCondition(this.simpleCondition2);
		
		ConditionsConfiguration.processObject(this.simpleCondition1);
		ConditionsConfiguration.processObject(this.simpleCondition2);
		
		assertFalse(this.simpleCondition1.isTrue());
	}
	
	@Test
	public void setComposedConditionToCancelGetNotConditionStateDifferentFromConditionToCancelState() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.andCondition);	
		
		assertFalse(this.notCondition.isTrue() == this.andCondition.isTrue());
	}
	
	@Test
	public void setComposedConditionToCancelMakeComposedConditionTrueGetNotConditionStateFalse() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.andCondition);	
		this.andCondition.addPreCondition(this.simpleCondition1);
		this.andCondition.addPreCondition(this.simpleCondition2);
		
		ConditionsConfiguration.processObject(this.simpleCondition1);
		ConditionsConfiguration.processObject(this.simpleCondition2);
		
		assertFalse(this.notCondition.isTrue());
	}
	
	@Test
	public void setComposedConditionToCancelAddPreConditionMakePreConditionTrueCheckComposedConditionToCancelIsTrue() throws ConditionDuplicatedException{
		this.notCondition = new NotDomainCondition(this.andCondition);
		this.notCondition.addPreCondition(this.simpleCondition3);
		this.andCondition.addPreCondition(this.simpleCondition1);
		this.andCondition.addPreCondition(this.simpleCondition2);
		
		ConditionsConfiguration.processObject(this.simpleCondition1);
		ConditionsConfiguration.processObject(this.simpleCondition2);
		ConditionsConfiguration.processObject(this.simpleCondition3);
		
		assertTrue(this.andCondition.isTrue());
	}
}
